# Class to send mail
=begin
Copyright (C) 2014 Enrique Rando

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

http://www.gnu.org/licenses/gpl-2.0.html
=end


require 'net/smtp'


class My_mail_sender
	# Object creation
	# Parameters:
	#	server:	mail server
	#	port: mail server port. :default for default port
	# 	cypher: cypher required by the server: :ssl, :tls, :none
	#	user, password:	credentials, if needed
	#	auth_type:	authentication mechanism: :login
	def initialize(server, port=:default, cypher=:tls, user=nil, password=nil, auth_type=nil)
		@cypher = cypher
		@auth_type = auth_type
		@user = user
		@password = password
		
		# Find out the port
		@port = case port
				when :default
					case cypher
					when :ssl
						Net::SMTP::default_ssl_port
					when :tls
						Net::SMTP::default_tls_port
					when :none
						Net::SMTP::default_port
					else
						raise "Invalid cypher: #{cypher.to_s}" 
					end
				else
					port
				end
					
		# Prepare connection
		@smtp = Net::SMTP.new(server, @port)
		@smtp.enable_tls if cypher==:tls
		@smtp.enable_ssl if cypher==:ssl	
	end
	
	# Send a message
	# Parameters:
	# 	body:	message text
	#	from, to, subject: mail headers
	#	body_content_type: mime type for the body
	#	attachments: array of hashes with attacment data (one hash per attachment). Keys are :file_name and :content_type
	#	cc, bcc:	mail headers
	#	delim: string to mark part beginning and end
	def send(body, from, to, subject="", body_content_type="text/plain", attachments = [], cc=nil, bcc=nil, delim="___MAIL_PART_BEGINS_ENDS")
		marker = "#{delim}===============0398553749=="
		
		# Array with mail lines
		msg = msgstr = [
			"From: #{from}",
			"To: #{to}"
			]
			
		msg << "Cc: #{cc}"  if not cc.nil?
		msg << "Bcc: #{bcc}"  if not bcc.nil?
		
		msg += [
			"Subject: #{subject}",
			"MIME-Version: 1.0",
			"Content-Type: multipart/mixed; boundary=#{marker}",
			"",
			"Multipart Message",
			"--#{marker}",
			"Content-Type: #{body_content_type}",
			"Content-Transfer-Encoding:8bit",
			"",
			"#{body}",
			"--#{marker}"
			]
				
		# Add attachments
		attachments.each do |attachment|
			# Base64 encode
			encoded_content = [File.read(attachment[:file_name])].pack("m")
			
			# Add to mail
			msg += [
				"Content-Type: #{attachment[:content_type]}; name=\"#{File.basename(attachment[:file_name])}\"",
				"Content-Transfer-Encoding:base64",
				"Content-Disposition: attachment; filename=\"#{File.basename(attachment[:file_name])}\"",
				"",
				"#{encoded_content}",
				"--#{marker}"]
		end
		
		# Generate the message
		msg = msg.join("\n")
		
		# Send
		myto = to.is_a?(Array) ? to : [to]
		@smtp.start('localhost', @user, @password, @auth_type) {|email|
			email.send_message(msg, from, myto)
		}
	end
end
